/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.taglib.core.util;

import com.blandware.atleap.common.util.StringUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>Describes item in context menu</p>
 * <p><a href="ContextMenuItem.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.8 $ $Date: 2007/12/08 17:51:56 $
 */
public class ContextMenuItem implements Serializable {

	/**
	 * ID of this menu item to use on JSP
	 */
	protected String id = null;

	/**
	 * Content of item which will be rendered on JSP page
	 */
	protected String content;

    /**
     * Whether this menu item is hidden
     */
    protected Boolean hidden = Boolean.FALSE;

	/**
	 * Reference to parent item
	 */
	protected ContextMenuItem parentItem = null;

	/**
	 * List of child items
	 */
	protected List childItems = new ArrayList();

	/**
	 * Creates new instance of MenuItem
	 */
	public ContextMenuItem() {
        hidden = Boolean.FALSE;
	}

	/**
	 * Creates new instance of ContextMenuItem and sets its content
     *
	 * @param content Content to set
	 */
	public ContextMenuItem(String content) {
		this.content = content;
	}

    /**
     * Returns context menu item content
     *
     * @return content
     */
	public String getContent() {
		return content;
	}

    /**
     * Sets context menu item content
     *
     * @param content content to set
     */
	public void setContent(String content) {
		this.content = content;
	}

    /**
     * Returns whether this menu item is hidden
     *
     * @return whether this menu item is hidden
     */
    public Boolean getHidden() {
        return hidden;
    }

    /**
     * Sets whether this menu item is hidden
     *
     * @param hidden whether this menu item is hidden
     */
    public void setHidden(Boolean hidden) {
        this.hidden = hidden;
    }

	/**
	 * Returns parent item of this one
	 *
	 * @return Parent item
	 */
	public ContextMenuItem getParentItem() {
		return parentItem;
	}

	/**
	 * Sets parent item for this one
	 *
	 * @param parentItem Parent item to set
	 */
	public void setParentItem(ContextMenuItem parentItem) {
		this.parentItem = parentItem;
	}

	/**
	 * Returns list of child items
	 *
	 * @return List of child items
	 */
	public List getChildItems() {
		return childItems;
	}

	public void setChildItems(List childItems) {
		for ( int i = 0; i < childItems.size(); i++ ) {
			ContextMenuItem item = (ContextMenuItem) childItems.get(i);
			addChildItem(item);
		}
	}

	/**
	 * Adds child item
	 *
	 * @param childItem Item to add as a child
	 */
	public void addChildItem(ContextMenuItem childItem) {
		if ( childItem != null ) {
			if ( childItem.getParentItem() != null ) {
				childItem.getParentItem().removeChildItem(childItem);
			}
			childItem.setParentItem(this);
		}
		childItems.add(childItem);
	}

	/**
	 * Removes child item
	 *
	 * @param childItem Child item to remove
	 */
	public void removeChildItem(ContextMenuItem childItem) {
		childItem.setParentItem(null);
		childItems.remove(childItem);
	}

	/**
	 * Returns ID of this item. If ID has not already been initialized, generates it according to parent item's ID and
	 * position of this item in the list of parent's children. Can return <code>null</code> if there is no parent item of this one,
	 * or parent item's ID is <code>null</code>
	 *
	 * @return ID of this item
	 */
	public String getId() {
		if ( id == null && parentItem != null ) {
			String parentId = parentItem.getId();
			if ( parentId != null ) {
				int pos = parentItem.getChildItems().indexOf(this);
				id = parentId + "__" + pos;
			}
		}
		return id;
	}

    /**
     * Sets ID of this item
     *
     * @param id ID to set
     */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * Generates JavaScript code, which will create client-side representation of this server-side object
	 *
	 * @return JavaScript code, which will create client-side representation of this server-side object
	 */
	public String getJavascriptCode() {
		StringBuffer code = new StringBuffer("new ContextMenuItem(");
		code.append("\"").append(getId()).append("\", ");
		code.append("\"").append(StringUtil.javascriptEscape(content)).append("\", ");
        code.append(hidden.toString());

		// append children one-by-one
		for ( int i = 0; i < childItems.size(); i++ ) {
			ContextMenuItem item = (ContextMenuItem) childItems.get(i);
			code.append(", ");
			if ( item != null ) {
				code.append(item.getJavascriptCode());
			} else {
				code.append(item);
			}
		}
		code.append(")");
		return code.toString();
	}

    /**
     * Returns list of all context menu items in following order: root, his
     * first child descendants, his second child descendants, ... his last child
     * descendants
     *
     * @return list of items in preorder
     */
    public List getAsPlainList() {
        List result = new ArrayList();
        result.add(this);

        for (int i = 0; i < childItems.size(); i++) {
            ContextMenuItem child = (ContextMenuItem) childItems.get(i);
            result.addAll(child.getAsPlainList());
        }

        return result;
    }
}
